package session.stateless.MRP.MaterialRequirement;

import entity.BillOfMaterial;
import entity.MRP.MaterialRequirement.IndividualMatReq;
import entity.MRP.MaterialRequirement.MRALineItem;
import entity.MRP.MaterialRequirement.MaterialReqAmdt;
import entity.MRP.MaterialRequirement.WeeklyMaterialReq;
import entity.MRP.ProductionPlan.PlannedWeeklyDemand;
import entity.Product;
import entity.RawMaterial;
import entity.SCM.MaterialLine;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javaclass.MaterialReqStt;
import javaclass.ProductType;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import session.stateless.ProductBeanLocal;


@Stateless
public class WeeklyMaterialReqBean implements WeeklyMaterialReqBeanLocal {

    @EJB
    BillOfMaterialBeanLocal billOfMaterialBeanLocal;
    @EJB
    ProductBeanLocal productBeanLocal;
    @EJB
    IngredientBeanLocal ingredientBeanLocal;
    @PersistenceContext(unitName = "M10-IS3102-ejbPU")
    private EntityManager entityManager;

    @Override
    public Long createWeeklyMaterialReq(long weeklyProdPlanID, long amtA, long amtB, long amtC, long amtD) {
        //fake input
        //=========================================================================================
        List<Product> products = productBeanLocal.getProductList();
        long quantity1 = amtA;
        long quantity2 = amtB;
        long quantity3 = amtC;
        long quantity4 = amtD;

        long kgBatch1 = Math.round(Math.ceil(quantity1 * products.get(0).getKgPerCase() / 200));
        long kgBatch2 = Math.round(Math.ceil(quantity2 * products.get(1).getKgPerCase() / 200));
        long kgBatch3 = Math.round(Math.ceil(quantity3 * products.get(2).getKgPerCase() / 200));
        long kgBatch4 = Math.round(Math.ceil(quantity4 * products.get(3).getKgPerCase() / 200));
        //=========================================================================================

        PlannedWeeklyDemand p = entityManager.find(PlannedWeeklyDemand.class, weeklyProdPlanID);

        WeeklyMaterialReq weeklyMaterialReq = new WeeklyMaterialReq();
        weeklyMaterialReq.setStatus(MaterialReqStt.PENDING);
        List<IndividualMatReq> individualMatReqs = new ArrayList<IndividualMatReq>();
        List<RawMaterial> listOfIngredients = ingredientBeanLocal.getListOfIngredients();
        double quantity = 0.0;
        for (RawMaterial i : listOfIngredients) {
            System.out.println(products.get(0).getProductType() + " " + i.getMaterialType());
            BillOfMaterial billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(0).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch1 * billOfMaterial.getAmountRequired();
            }

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(1).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch2 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(2).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(2).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch3 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(3).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(3).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch4 * billOfMaterial.getAmountRequired();
            }
//
//            System.out.println(quantity);
//            System.out.println(products.get(1).getProductType() + " " + i.getMaterialType());

            System.out.println("Success");
            IndividualMatReq individualMatReq = new IndividualMatReq();
            individualMatReq.setRawMaterial(i);
            individualMatReq.setTotalAmountRequired(quantity);
            entityManager.persist(individualMatReq);
            individualMatReqs.add(individualMatReq);
            quantity = 0.0;
        }
        weeklyMaterialReq.setIndividualMatReqs(individualMatReqs);
        weeklyMaterialReq.setPlannedWeeklyDemand(p);
        entityManager.persist(weeklyMaterialReq);

        p.setWeeklyMaterialReq(weeklyMaterialReq);

        for (IndividualMatReq i : weeklyMaterialReq.getIndividualMatReqs()) {
            i.setWeeklyMaterialRequirement(weeklyMaterialReq);
        }
        entityManager.flush();
        return weeklyMaterialReq.getId();
    }

    @Override
    public Long updateWeeklyMaterialReq(long weeklyProdPlanID, long amtA, long amtB, long amtC, long amtD) {
        //fake input
        //=========================================================================================
        List<Product> products = productBeanLocal.getProductList();
        long quantity1 = amtA;
        long quantity2 = amtB;
        long quantity3 = amtC;
        long quantity4 = amtD;

        long kgBatch1 = Math.round(Math.ceil(quantity1 * products.get(0).getKgPerCase() / 200));
        long kgBatch2 = Math.round(Math.ceil(quantity2 * products.get(1).getKgPerCase() / 200));
        long kgBatch3 = Math.round(Math.ceil(quantity3 * products.get(2).getKgPerCase() / 200));
        long kgBatch4 = Math.round(Math.ceil(quantity4 * products.get(3).getKgPerCase() / 200));
        //=========================================================================================

        PlannedWeeklyDemand p = entityManager.find(PlannedWeeklyDemand.class, weeklyProdPlanID);

        WeeklyMaterialReq weeklyMaterialReq = entityManager.find(WeeklyMaterialReq.class, p.getWeeklyMaterialReq().getId());

        weeklyMaterialReq.setStatus(MaterialReqStt.PENDING);
        List<IndividualMatReq> individualMatReqs = new ArrayList<IndividualMatReq>();
        List<RawMaterial> listOfIngredients = ingredientBeanLocal.getListOfIngredients();
        double quantity = 0.0;



        for (RawMaterial i : listOfIngredients) {
            System.out.println(products.get(0).getProductType() + " " + i.getMaterialType());
            BillOfMaterial billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(0).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch1 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(1).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(1).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch2 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(2).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(2).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch3 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(3).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(3).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch4 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(1).getProductType() + " " + i.getMaterialType());

            for (IndividualMatReq ind : weeklyMaterialReq.getIndividualMatReqs()) {
                if (ind.getRawMaterial().equals(i)) {
                    ind.setTotalAmountRequired(ind.getTotalAmountRequired() + quantity);
                    break;
                }
            }
            entityManager.flush();
            quantity = 0.0;
        }
        return weeklyMaterialReq.getId();
    }

    @Override
    public Long createMaterialReqAmdt(long weeklyMaterialReqId, long amtA, long amtB, long amtC, long amtD) {
        //fake input
        //=========================================================================================
        List<Product> products = productBeanLocal.getProductList();
        long quantity1 = amtA;
        long quantity2 = amtB;
        long quantity3 = amtC;
        long quantity4 = amtD;

        long kgBatch1 = Math.round(Math.ceil(quantity1 * products.get(0).getKgPerCase() / 200));
        long kgBatch2 = Math.round(Math.ceil(quantity2 * products.get(1).getKgPerCase() / 200));
        long kgBatch3 = Math.round(Math.ceil(quantity3 * products.get(2).getKgPerCase() / 200));
        long kgBatch4 = Math.round(Math.ceil(quantity4 * products.get(3).getKgPerCase() / 200));
        //=========================================================================================

        WeeklyMaterialReq wMR = entityManager.find(WeeklyMaterialReq.class, weeklyMaterialReqId);

        MaterialReqAmdt mRA = new MaterialReqAmdt();
        List<IndividualMatReq> individualMatReqs = new ArrayList<IndividualMatReq>();
        List<RawMaterial> listOfIngredients = ingredientBeanLocal.getListOfIngredients();
        double quantity = 0.0;
        for (RawMaterial i : listOfIngredients) {
//            System.out.println(products.get(0).getProductType() + " " + i.getMaterialType());
            BillOfMaterial billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(0).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch1 * billOfMaterial.getAmountRequired();
            }
//
//            System.out.println(quantity);
//            System.out.println(products.get(1).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(1).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch2 * billOfMaterial.getAmountRequired();
            }
//
//            System.out.println(quantity);
//            System.out.println(products.get(2).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(2).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch3 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(3).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(3).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch4 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(1).getProductType() + " " + i.getMaterialType());

            IndividualMatReq individualMatReq = new IndividualMatReq();
            individualMatReq.setRawMaterial(i);
            individualMatReq.setTotalAmountRequired(quantity);
            entityManager.persist(individualMatReq);
            individualMatReqs.add(individualMatReq);
            quantity = 0.0;
        }
        mRA.setIndividualMaterialRequirements(individualMatReqs);
        List<MRALineItem> lineItems = new ArrayList<MRALineItem>();
        MRALineItem li = new MRALineItem();
        li.setProduct(entityManager.find(Product.class, ProductType.NUTS));
        li.setQuantity(amtA);
        entityManager.persist(li);
        lineItems.add(li);

        li = new MRALineItem();
        li.setProduct(entityManager.find(Product.class, ProductType.FRUITS));
        li.setQuantity(amtB);
        entityManager.persist(li);
        lineItems.add(li);

        li = new MRALineItem();
        li.setProduct(entityManager.find(Product.class, ProductType.CHOCOLATE_NUTS));
        li.setQuantity(amtC);
        entityManager.persist(li);
        lineItems.add(li);

        li = new MRALineItem();
        li.setProduct(entityManager.find(Product.class, ProductType.REDCURRANT_FRUITS));
        li.setQuantity(amtD);
        entityManager.persist(li);
        lineItems.add(li);

        mRA.setMraLineItems(lineItems);

        Calendar c = Calendar.getInstance();
        String date = c.get(Calendar.DAY_OF_MONTH) + "/" + c.get(Calendar.MONTH + 1) + "/" + c.get(Calendar.YEAR);
        mRA.setDateCreated(date);

        mRA.setStatus(MaterialReqStt.PENDING);

        mRA.setWeeklyMaterialReq(wMR);
        entityManager.persist(mRA);

        for (IndividualMatReq i1 : mRA.getIndividualMaterialRequirements()) {
            for (IndividualMatReq i2 : wMR.getIndividualMatReqs()) {
                if (i1.getRawMaterial() == i2.getRawMaterial()) {
                    i2.setTotalAmountRequired(i2.getTotalAmountRequired() + i1.getTotalAmountRequired());
                    break;
                }
            }
        }
        wMR.setMaterialReqAmdt(mRA);
        entityManager.flush();
        return mRA.getId();
    }

    @Override
    public Long updateWeeklyMaterialReqAmdt(long weeklyMaterialReqId, long amtA, long amtB, long amtC, long amtD) {
        //fake input
        //=========================================================================================
        List<Product> products = productBeanLocal.getProductList();
        long quantity1 = amtA;
        long quantity2 = amtB;
        long quantity3 = amtC;
        long quantity4 = amtD;

        long kgBatch1 = Math.round(Math.ceil(quantity1 * products.get(0).getKgPerCase() / 200));
        long kgBatch2 = Math.round(Math.ceil(quantity2 * products.get(1).getKgPerCase() / 200));
        long kgBatch3 = Math.round(Math.ceil(quantity3 * products.get(2).getKgPerCase() / 200));
        long kgBatch4 = Math.round(Math.ceil(quantity4 * products.get(3).getKgPerCase() / 200));
        //=========================================================================================

        WeeklyMaterialReq wMR = entityManager.find(WeeklyMaterialReq.class, weeklyMaterialReqId);

        MaterialReqAmdt mRA = new MaterialReqAmdt();
        List<IndividualMatReq> individualMatReqs = new ArrayList<IndividualMatReq>();
        List<RawMaterial> listOfIngredients = ingredientBeanLocal.getListOfIngredients();
        double quantity = 0.0;



        for (RawMaterial i : listOfIngredients) {
//            System.out.println(products.get(0).getProductType() + " " + i.getMaterialType());
            BillOfMaterial billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(0).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch1 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(1).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(1).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch2 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(2).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(2).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch3 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(3).getProductType() + " " + i.getMaterialType());

            billOfMaterial = billOfMaterialBeanLocal.findBillOfMaterial(products.get(3).getProductType(), i.getMaterialType());
            if (billOfMaterial != null) {
                quantity += kgBatch4 * billOfMaterial.getAmountRequired();
            }

//            System.out.println(quantity);
//            System.out.println(products.get(1).getProductType() + " " + i.getMaterialType());

            System.out.println("Success");
            for (IndividualMatReq ind : mRA.getIndividualMaterialRequirements()) {
                if (ind.getRawMaterial().equals(i)) {
                    ind.setTotalAmountRequired(ind.getTotalAmountRequired() + quantity);
                    break;
                }
            }
            for (IndividualMatReq ind : wMR.getIndividualMatReqs()) {
                if (ind.getRawMaterial().equals(i)) {
                    ind.setTotalAmountRequired(ind.getTotalAmountRequired() + quantity);
                    break;
                }
            }
            entityManager.flush();
            quantity = 0.0;
        }
        return mRA.getId();
    }

    @Override
    public List<MaterialLine> createMaterialLine(Long weeklyMaterialReqID) {

        WeeklyMaterialReq weeklyMaterialReq = entityManager.find(WeeklyMaterialReq.class, weeklyMaterialReqID);
        if (weeklyMaterialReq == null) {
            System.out.println("This WeeklyMaterialReq Does Not Exist!");
            return null;
        }
        List<MaterialLine> materialLineList = new ArrayList<MaterialLine>();

        List<IndividualMatReq> individualMatReq = weeklyMaterialReq.getIndividualMatReqs();
        for (int i = 0; i < individualMatReq.size(); i++) {
            MaterialLine materialLine = new MaterialLine();
            materialLine.setRawMaterial(individualMatReq.get(i).getRawMaterial());
            long amount = individualMatReq.get(i).getTotalAmountRequired().longValue();
            materialLine.setQuantity(new Long(amount));
            materialLineList.add(materialLine);
        }
        return materialLineList;
    }

    @Override
    public List<WeeklyMaterialReq> getWeeklyMaterialReq() {
        Query q = entityManager.createQuery("SELECT c FROM WeeklyMaterialReq c");
        
        List<WeeklyMaterialReq> weeklyMaterialReqList = q.getResultList();
        if(!weeklyMaterialReqList.isEmpty()){
            for(int i= weeklyMaterialReqList.size()-1; i>=0; i--){
                double a = weeklyMaterialReqList.get(i).getIndividualMatReqs().get(0).getTotalAmountRequired().doubleValue();
                if(a==0){
                    weeklyMaterialReqList.remove(i);
                }
            }
        }
        return weeklyMaterialReqList;
    }

    @Override
    public boolean changeState(Long weeklyMaterialReqID) {
        WeeklyMaterialReq weeklyMaterialReq = entityManager.find(WeeklyMaterialReq.class, weeklyMaterialReqID);
        if (weeklyMaterialReq == null) {
            System.out.println("This WeeklyMaterialReq Does Not Exist!");
            return false;
        }
        if (weeklyMaterialReq.getStatus().equals(MaterialReqStt.PENDING)) {
            weeklyMaterialReq.setStatus(MaterialReqStt.PROCESSED);
            return true;
        }

        return false;

    }
    
    @Override
    public List<WeeklyMaterialReq> getPendingWeeklyMaterialReq() {
        Query q = entityManager.createQuery("SELECT c FROM WeeklyMaterialReq c WHERE c.status = :status");
        q.setParameter("status", MaterialReqStt.PENDING);

        List<WeeklyMaterialReq> weeklyMaterialReqList = q.getResultList();
        if(!weeklyMaterialReqList.isEmpty()){
            for(int i= weeklyMaterialReqList.size()-1; i>=0; i--){
                double a = weeklyMaterialReqList.get(i).getIndividualMatReqs().get(0).getTotalAmountRequired().doubleValue();
                if(a==0){
                    weeklyMaterialReqList.remove(i);
                }
            }
        }
        return weeklyMaterialReqList;
    }
}
            
            
            
            
            
            
            